--[[
	Copyright (C) Udorn (Blackhand)

	This program is free software; you can redistribute it and/or
	modify it under the terms of the GNU General Public License
	as published by the Free Software Foundation; either version 2
	of the License, or (at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
--]]

--[[
	Widget for displaying a popup menu.
--]]

vendor.PopupMenu = {}
vendor.PopupMenu.prototype = {}
vendor.PopupMenu.metatable = {__index = vendor.PopupMenu.prototype}

--[[ 
	Sorts according to order value.
--]]
local function _SortEntries(a, b)
	return a.order < b.order
end

--[[
	Toggle button callback.
--]]
local function _ToggleClicked(but, arg1, arg2, checked)
	local item = arg1
	vendor.Vendor:Debug("ToggleClicked checked: %s passValue: %s", checked, item.passValue)
	-- we have to toggle the checked value
	local checked = not checked
	if (item.type == "multiselect") then
		if (checked) then
			-- deselect all others
			for k, v in pairs(item.values) do
				if (k ~= arg2 and item.get({arg=k})) then
					item.set({arg=k}, false)
				end
			end
		else
			-- ensure that at least one other item is selected
			local hasOther = false
			for k, v in pairs(item.values) do
				if (k ~= arg2 and item.get({arg=k})) then
					hasOther = true
					break
				end
			end
			if (not hasOther) then
				-- select first other
				for k, v in pairs(item.values) do
					if (k ~= arg2) then
						item.set({arg=k}, true)
						break
					end
				end
			end
		end
	end
	item.set({arg=arg2}, checked)
end

--[[
	Init function for blizzard's dropdown menu.
--]]
local function _DropDown_Initialize(self, level, menuList)
	level = level or 1
	local info = UIDropDownMenu_CreateInfo()
   	if (level == 1) then
    	for key, item in pairs(menuList) do
    		info.hasArrow = false -- no submenu
   			info.text = item.text
   			info.func = item.func
   			info.arg1 = item.arg1
   			if (item.disabledFunc) then
  				info.disabled = item.disabledFunc()
   			end
    		if (item.type == "execute") then
       			info.notCheckable = true
       			UIDropDownMenu_AddButton(info, level)
       		elseif (item.type == "toggle") then
       			info.notCheckable = false
       			info.checked = item.get({arg=item.passValue})
       			info.func = _ToggleClicked
       			info.arg1 = item
       			info.arg2 = item.passValue
       			UIDropDownMenu_AddButton(info, level)
   			elseif (item.type == "multiselect") then
   				info.notCheckable = false
   				info.func = _ToggleClicked
   				info.arg1 = item
   				for k, v in pairs(item.values) do
   					info.text = v
       				info.checked = item.get({arg=k})
       				info.arg2 = k 
       				UIDropDownMenu_AddButton(info, level)
   				 end
       		else
       			assert(false)
       		end
       		
       		wipe(info)
     	end
   	end
end

--[[
	Adds the entries to the frame.
--]]
local function _InitMenu(self)
	-- sort cmds
	local cmds = {}
	for k,v in pairs(self.entries) do
		v.arg1 = self.arg1
		table.insert(cmds, v)
	end
	table.sort(cmds, _SortEntries)
	-- create menu
 	self.frame = CreateFrame("Frame", self.frameName, UIParent, "UIDropDownMenuTemplate")
 	self.frame.ctrl = self
 	self.cmds = cmds
	UIDropDownMenu_Initialize(self.frame, _DropDown_Initialize, "MENU", 1, self.cmds)
end

--[[
	Creates a new instance. The entries are passed to SetEntries.
--]]
function vendor.PopupMenu:new(frameName, entries, arg1)
	local instance = setmetatable({}, self.metatable)
	instance.nesting = 0
	instance.frameName = frameName
	instance:SetEntries(entries, arg1)
	return instance
end


--[[
	Sets the list of entries for this menu. Thats a table of the following form:
	{
    	scan = {
    		type = "execute"
    		text = L["Scan"],
    		func = function() vendor.Scanner:Scan() end,
    		disabledFunc = function() return not vendor.Scanner:IsScanning() end,
    		order = 1
    	},
    	fast = {
    		type = "toggle"
    		text = L["Enable fast scan"],
    		func = function() vendor.Sniper:ToggleFast() end,
    		checked = true -- function returning boolean is also ok
    		get = function(name) => value
    		set = function(name, value)
    		passValue = name (string) 
    		order = 2
    	},
    }
--]]
function vendor.PopupMenu.prototype:SetEntries(entries, arg1)
	self.entries = entries
	self.arg1 = arg1
	_InitMenu(self)
end

--[[
	Shows the popup menu
--]]
function vendor.PopupMenu.prototype:Show()
	ToggleDropDownMenu(nil, nil, self.frame, "cursor", -20, 0, self.cmds)
end
